package com.ztr.suanfa.aes;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

public class AESExample {
    public static void main(String[] args) throws Exception {
        String plainText = "z123456789";
        String key = "ThisIsSecretKey1"; // 密钥长度必须是16、24或32个字符

        byte[] encryptedBytes = encrypt(plainText, key);
        String encryptedText = Base64.getEncoder().encodeToString(encryptedBytes);
        System.out.println("Encrypted Text: " + encryptedText);

        String decryptedText = decrypt(encryptedBytes, key);
        System.out.println("Decrypted Text: " + decryptedText);
    }

    /**
     * 用于加密一个字符串
     *
     * @param plainText
     * @param key
     * @return
     * @throws Exception
     */
    public static byte[] encrypt(String plainText, String key) throws Exception {
        // 使用输入的key字符串（转换为UTF-8字节）和"AES"算法创建一个SecretKeySpec对象
        SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "AES");

        // 获取一个Cipher实例，用于加密或解密。这里指定的模式是"AES/ECB/PKCS5Padding"，表示使用AES算法、ECB模式和PKCS5填充方式。
        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");

        // 初始化cipher对象，设置它为加密模式，并传入之前创建的secretKey
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);

        // plainText字符串被转换为UTF-8字节，然后传递给doFinal进行加密。加密后的结果是一个字节数组，这个数组就是方法返回的结果。
        return cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));
    }

    /**
     * 用于解密之前使用AES算法加密的数据
     *
     * @param encryptedBytes
     * @param key
     * @return
     * @throws Exception
     */
    public static String decrypt(byte[] encryptedBytes, String key) throws Exception {
        SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "AES");
        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");

        // 初始化cipher对象，设置它为解密模式，并传入之前创建的secretKey
        cipher.init(Cipher.DECRYPT_MODE, secretKey);

        // 使用cipher的doFinal方法执行解密操作，传入加密后的字节数组encryptedBytes，并返回解密后的字节数组decryptedBytes。
        byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
        return new String(decryptedBytes, StandardCharsets.UTF_8);
    }

}
